你曾經有,放進去的圖片過大,結果超過畫布範圍,沒有控制點可以拉的窘境嗎?
或是想要畫布的圖形有出血效果,卻難以判斷圖形究竟已經超出邊框多少嗎?
您的救星來了!
在畫布外可以看見控制點的做法!
而輸出的圖片像這樣,就跟想輸出的尺寸一樣:
(微錯誤示範XD 這張圖在下載時忘記把 clipPath 加上 strokeWidth: 0
屬性,已導致左邊上邊出現黑線🌚,想避免此情況請看後續說明喔 )
到底是怎麼做的呢?
方法其實不難,讓我們來一探究竟~
這段程式碼的構成構想如下:
這裡我們把最終想輸出的區塊稱為 工作區
好了
controlsAboveOverlay: true
工作區
(你可以設置任何你最終想輸出的尺寸)。工作區
範圍內的物件會顯示在畫布上,因為他在 clipPath 遮罩之內,在 工作區
之外的地方只會顯示控制點。工作區
內的內容,使用的方式是用與當初設置 工作區
clipPath 一樣的參數(位置、大小、位移等)。這樣就能無痛擁有控制點了~
獲取畫布元素,初始化 Fabric.js 畫布:
!!!畫布須設置 controlsAboveOverlay: true
讓控制點得以顯現在 clipPath 的畫面以外
const canvasEl = document.getElementById("canvas");
const canvas = new fabric.Canvas(canvasEl, {
backgroundColor: "#fff",
controlsAboveOverlay: true // 要達成這個效果的重要設置
//要讓物件控制項(邊框/控制項)在覆蓋圖像之上渲染。
});
計算畫布中心點:
抓到畫布中心才能以此為基準,讓每次畫布都在視窗中心
var centerX = canvas.width / 2;
var centerY = canvas.height / 2;
設置導出畫布的配置:
重要!要在 clipPath 上設置 strokeWidth: 0
,不然輸出圖左跟上邊會有黑邊,並且些微偏移(請見上面的錯誤示範輸出圖XD)
const exportCanvasConfig = {
left: centerX*0.2,
top: centerY*0.2,
width: centerX*0.6,
height: centerY*0.6,
strokeWidth: 0 //這邊要設定 0 !
};
設置畫布大小為全螢幕
function resizeCanvas() {
canvas.setWidth(window.innerWidth);
canvas.setHeight(window.innerHeight);
updateClipPath();
}
創建並更新 clipPath:
function updateClipPath() {
var clipPath = new fabric.Rect(exportCanvasConfig); //依據設定檔來設置 clipPath
canvas.clipPath = clipPath;
canvas.renderAll();
}
監聽視窗大小變化:
因為畫布在設定時是隨著視窗尺寸變動的,所以每次改變視窗尺寸時也要跟著調整 canvas 大小。
window.addEventListener("resize", resizeCanvas);
添加導出按鈕並設置點擊事件:
const onDownloadImage = () => {
const data = canvas.toDataURL({
...exportCanvasConfig, //使用和 clipPath 相同大小位置的設定
format: "jpeg",
quality: 1,
});
const a = document.createElement("a");
a.href = data;
a.download = "my-draw.jpg";
a.click();
};
document.getElementById("download").addEventListener("click", onDownloadImage);